package com.nstar.base.util
{
	import com.nstar.base.controls.TreeSelectComboBox;
	
	import flash.events.MouseEvent;
	import flash.net.SharedObject;
	import flash.utils.getDefinitionByName;
	import flash.utils.getQualifiedClassName;
	
	import mx.collections.ArrayCollection;
	import mx.controls.ComboBox;
	import mx.controls.LinkButton;
	import mx.controls.TextInput;
	import mx.controls.VRule;
	import mx.core.Container;
	
	/**
	 * 对象工具类
	 * 
	 * @author zhucm
	 * @since 2007-09
	 */
	public class ObjectUtils
	{
		public static function copy(toObj:Object, fromObj:Object) : Object
		{
			for (var name:* in fromObj) {
				toObj[name] = fromObj[name];
			}
			
			return toObj;
		}
		
		/**
		 * 
		 * 在容器中添加LinkButton，并添加相应处理事件
		 * 用于需要添加多个连续的LinkButton的地方
		 * 
		 * container		:容器名称
		 * caption			:LinkButton标题
		 * listener			:LinkButton单击事件
		 * addVRule			:是否添加垂直分割符
		 * defaultHeight	:LinkButton默认高度
		 * 
		 * @author:zhucm
		 * @date:2007.9.7
		 * 
		 */ 
		public static function addLink(container:Container,caption:String,listener:Function=null,
			addVRule:Boolean = true,defaultHeight:int=20,icon:Class = null):LinkButton{
			var lb:LinkButton = new LinkButton();
			lb.label = caption;
			lb.height = defaultHeight;
			//设置样式
			lb.setStyle("fontWeight","normal");
			//其它样式根据容器的样式而来
			lb.setStyle("color",container.getStyle("color"));
			lb.setStyle("fontSize",container.getStyle("fontSize"));
			lb.setStyle("fontWeight",container.getStyle("fontWeight"));
			lb.setStyle("fontStyle",container.getStyle("fontStyle"));
			lb.setStyle("textDecoration",container.getStyle("textDecoration"));
			//设置图标
			if (icon!=null){
				lb.setStyle("icon",icon);
			}
			//添加事件处理
			if (listener!=null){
				lb.addEventListener(MouseEvent.CLICK,listener);	
			}
			container.addChild(lb);
			//添加分割符
			if (addVRule){
				var vr:VRule = new VRule();
				vr.height = 12;
				container.addChild(vr);					
			}
			return lb;
		}
		
		//保存窗口内的组件属性设置，保存到本地共享文件中
		public static function	setMemory(container:Container,url:String):void{
			var so:SharedObject = SharedObject.getLocal(url);
			var list:ArrayCollection = new ArrayCollection();
			//循环处理容器内的组件
			for(var i:int=0;i<container.getChildren().length;i++){
				var child:Object = container.getChildAt(i);
				//目前处理的组件有 TextInput，ComboBox，TreeSelectComboBox
				if ((child is TextInput) || child is ComboBox ||
					 child is TreeSelectComboBox){
					list.addItem({label:child.name,data:child.text});
				}
				
			}
			so.data.params = list;
			so.flush();
		}
		
		//取得容器内的属性设置，保存到本地共享文件中
		public static function getMemory(container:Container,url:String):void{
			var so:SharedObject = SharedObject.getLocal(url);
			var list:ArrayCollection = ArrayCollection(so.data.params);
			if (list != null && list.length>0){
				//循环处理容器内的组件
				for(var i:int=0;i<container.getChildren().length;i++){
					var child:Object = container.getChildAt(i);
					var idx:int = ArrayUtils.searchCollectionItem(list,"label",child.name);
					if (idx !=-1){
						//目前处理的组件有 TextInput，ComboBox，TreeSelectComboBox
						if ((child is TextInput) || child is ComboBox ||
							 child is TreeSelectComboBox){
							child.text = list[idx].data;
						}						
					}
				}
			}
		}
		
		//反序列化对象,callback是处理类路径的回调方法，因为可能Java中对应的类路径和AS中不一致
		//下面一个函数 packageHandlerCallback 提供了一个默认的路径处理方法回调函数
		//你也可以自己定义一个
		public static function deserialize(object:Object,
			callback:Function = null,...args):*{
				
			function convert(item:Object,propType:String):Object{
				switch(propType){
					case "Date"://日期的特殊处理，因为日期类型返回的是时间的毫秒表示方法
						return new Date(item);
					default :
						return item;
				}
			}
			
			var classKey:String = "class";
			//如果对象中包括 class 属性，且值不为空
			if(object.hasOwnProperty(classKey) && object[classKey]!=null){
				var className:String = object[classKey] as String;
				//处理JAVA类和AS类的包名不一致问题
				if(callback!=null){
					className =callback.call(null,className,args);
					object[classKey]=className;
				}
				//根据反射去动态生成类
				var clazz:Class = getDefinitionByName(className) as Class;
				var asObj = new clazz();
				for(var item:Object in object){
					if(object[item]!=null && object[item].hasOwnProperty(classKey)){
						asObj[item]= deserialize(object[item],callback,args);
					}else if(item.toString()!=classKey){
						var propType:String = getQualifiedClassName(asObj[item.toString()]);
						asObj[item] = convert(object[item],propType);
					}
				}
				return asObj;
			}
			return null;
		}
		
		//提供一个默认的包路径处理方法
		//usage: packageHandlerCallback("com.nstar.countdown.CountDown","com.hacoc.countdown");
		//	返回结果为 com.hacoc.countdown.CountDownVO
		public static function packageHandlerCallback(source:String,dest:String):String{
			var arySource:Array = source.split(".");
			return  dest+"."+arySource[arySource.length-1]+"VO";//添加个VO的后缀
		}		
		
		
		//反序列化数组
		public static function deserializeArray(ary:Object,
			callback:Function = null,...args):ArrayCollection{
			var result:ArrayCollection = new ArrayCollection();
			if(ary!=null && ary.length>0){
				for(var i:int=0;i<ary.length;i++){
					var item = deserialize(ary[i],callback,args);
					if(item!=null){
						result.addItem(item);
					}
				}
			}
			return result;
		}
		
		//对象中是否
		private static function existKey(target:Object,key:String):Boolean{
			if(target){
				for(var item:Object in target){
					if(item.toString()==key) return true;
				}
			}
			return false;	
		}
		
		//返回target中指定数据的索引，target是Array或ArrayCollection
		public static function indexOf(target:Object,key:String=null,value:String=null):int{
			if(target==null) return -1;
			if(!(target is Array) && !(target is ArrayCollection)) return -1;
			
			for(var i:int=0;i<target.length;i++){
				if(key!=null && key!=""){
					if(target[i][key].toString()==value) return i;
				}else{
					if(target[i] == value) return i;
				}
			}
			
			return -1;
		}
		
		//忽略源数组中removeIndex索引的数据，并生成新的数组
		public static function reArray(source:Object,removeIndex:int):Array{
			var ary:Array = new Array();
			if(source!=null && removeIndex>-1){
				for(var i:int=0;i<source.length;i++){
					if(i == removeIndex) continue;//
					ary.push(source[i]);
				}
			}
			return ary;
		}
		
	}
}